package com.zilue.hfqueue.queue.block;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * Created by ZD on 2017/5/4.
 */
public class HFQueueReadBlock {
    private final int FILE_MAX_SIZE = 1024 * 1024 * 32;
    public static final int INT_SIZE = 4;
    private final String mode = "r";
    private RandomAccessFile file;
    private MappedByteBuffer buffer;
    private final String POSTFIX = ".block";
    private int block_num;


    public HFQueueReadBlock(final String path, final String toipc, int blockNum, int index) throws IOException {
        block_num = blockNum;
        file = new RandomAccessFile(path + "HFQueue_" + toipc + "_" + block_num + POSTFIX, mode);
        if (FILE_MAX_SIZE != file.length()) {
            file.setLength(FILE_MAX_SIZE);
        }
        buffer = file.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length()).force();
        buffer.position(index);
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    if (file != null)
                        file.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
        }));
    }


    public byte[] readData(int postion) {
        buffer.position(postion);
        int length = buffer.getInt();
        if (length == 0)
            return null;
        try {
            byte[] bytes = new byte[length];
            buffer.get(bytes);
            return bytes;
        } catch (OutOfMemoryError e) {
            System.out.println(Thread.currentThread().getId() + "|" + block_num + "|" + postion + "|" + length);
            throw new RuntimeException(e);
        }
    }

    public void close() {
        try {
            if (file != null)
                file.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


}
